# -*- coding:utf-8 -*-
import json
import logging
import os
import re

from langchain.chat_models import ChatOpenAI
from langchain import FAISS, OpenAI
from langchain import LLMChain, PromptTemplate
from langchain.llms import BaseLLM
from typing import Dict, List, Any
from langchain.chains.base import Chain
from pydantic import BaseModel, Field

from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema import Document

# @Time    : 2023/5/12 16:57
# @Author  : lishuaichao
# @Email   : lishuaichao@lingxi.ai
# @File    : faq.py
# @Software: LLM_internal

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    level=logging.INFO)
os.environ["OPENAI_API_KEY"] = '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'



class UserChain(LLMChain):
    """从用户对话过程中提取用户信息，并根据已有信息推理未知信息"""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        user_prompt_template = (
            """
您正在接到一通保险销售员的电话，他正在向您推销一种保险产品。请您以普通消费者用户的身份与销售员进行对话，回答他的问题并提出疑问和需求。请回答销售员的问题，并保持礼貌和语气。

返回要求
###
如果销售员是简单话术问询（比如，您还记得吗？您知道吗），那么你随机返回：嗯、知道了、不记得了；
如果销售员在询问你的职业，要从{career_list}这个列表中随机选取一个职业进行回答；
如果销售员在询问你的婚育情况，要从{marriage_list}这个列表中随机选取一个婚育情况进行回答；
###

示例1
销售员: 您好，我是泰康的客户经理，我姓刘，今天致电是给您做个回访，您之前有免费领取过咱们泰康的一个意外险，这个您还记得嘛？  
用户: 嗯
示例2
销售员: 那今天给您致电，是泰康26周年庆，响应国家号召，完善老百姓的保障，给您之前的保单升级成疾病，意外都能保的全险，和医社保做补充，因为医社保是有一定报销比例的，并且进口药自费药都是没办法报销的，这个您知道吧？
用户: 知道
示例3
销售员: 那升级之后的服务，以后咱们不管因为疾病还是意外去医院住院治疗，都是100%报销合同约定的医疗费用，进口药自费药也都可以报，但是不是所有的客户都有这个名额，对职业健康有一定要求，冒昧问下您是做什么工作的啊？
用户: 我是的
示例4
销售员: 冒昧问下您结婚了吗？
用户: 嗯，我孩子都可以打酱油了
示例5
销售员: 那您孩子多大了？
用户: 20了，快大学毕业了

当前销售员的问题是:{recent_sales_utterance}
请返回你的回应，回应里不要带有'用户: '这样的前缀。
        """
        )
        prompt = PromptTemplate(
            template=user_prompt_template,
            input_variables=["recent_sales_utterance","career_list","marriage_list"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)


class GptUser(Chain, BaseModel):
    """Controller model for the Gpt User."""
    user_chain: UserChain = Field(...)

    @property
    def input_keys(self) -> List[str]:
        return []

    @property
    def output_keys(self) -> List[str]:
        return []

    def _call(self, inputs: Dict[str, Any], conversation_history='',recent_sales_utterance='',career_list=[],marriage_list=[]) -> None:
        gpt_user_response = self.user_chain.run(
            conversation_history=conversation_history,
            recent_sales_utterance=recent_sales_utterance,
            career_list=career_list,
            marriage_list=marriage_list
        )
        logging.info("gpt_user_response is {},type:{}".format(gpt_user_response, type(gpt_user_response)))
        return gpt_user_response

    @classmethod
    def from_llm(
            cls, llm: BaseLLM, verbose: bool = True, **kwargs
    ) -> "SalesGPT":
        """Initialize the SalesGPT Controller."""
        user_chain = UserChain.from_llm(
            llm, verbose=verbose
        )
        return cls(
            user_chain=user_chain,
            verbose=verbose,
            **kwargs,
        )




if __name__ == '__main__':
    llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
    gpt_user = GptUser.from_llm(llm, verbose=True,)
    context = ["销售员: 您好，我是泰康的客户经理，我姓刘，今天致电是给您做个回访，您之前有免费领取过咱们泰康的一个意外险，这个您还记得嘛？",
              "用户: 嗯" ,
              "销售员: 那今天给您致电，是泰康26周年庆，响应国家号召，完善老百姓的保障，给您之前的保单升级成疾病，意外都能保的全险，和医社保做补充，因为医社保是有一定报销比例的，并且进口药自费药都是没办法报销的，这个您知道吧" ,
              "用户: 知道" ,
              "销售员：那升级之后的服务，以后咱们不管因为疾病还是意外去医院住院治疗，都是100%报销合同约定的医疗费用，进口药自费药也都可以报，但是不是所有的客户都有这个名额，对职业健康有一定要求，冒昧问下您是做什么工作的啊？" ,
              "用户：写代码的" ,
              "销售员：那就没问题，另外今天还可以给您申请两个家庭名额，让您的家人享受同样的保障，费用也很轻松，平均每天几块钱就可以了，您目前结婚了嘛？" ,
              "用户：嗯" ,
              "销售员：嗯，您目前有孩子了嘛？"]
    gpt_user._call(inputs={}, conversation_history='\n'.join(context),recent_sales_utterance=context[-1])

    # print(faq_query.query('我不需要,没闲钱', chat_context=context))
    # print(faq_query.query('我有社保,不需要买保险', chat_context=context))
    # print(faq_query.query('我考虑一下好吧,挂了', chat_context=context))
    # print(faq_query.query('我跟我老公商量一下,需要的话我打给你', chat_context=context))
    # print(faq_query.query('和找保险经纪人买的有什么区别?', chat_context=context))
    # print(faq_query.query('有什么特色服务吗?', chat_context=context))